#ifndef __WINBUF_H__
#define __WINBUF_H__

#include <nxos.h>
#include "winbuf_conf.h"
#include <libwinbuf.h>

#define WINBUF_PIXEL_SIZE 4

#define ___WINBUF_ARGB(a, r, g, b)   (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) 
#define WINBUF_ARGB(a, r, g, b)      ___WINBUF_ARGB((a) & 0xff, (r)  & 0xff, (g) & 0xff, (b) & 0xff)
#define WINBUF_RGB(r, g, b)          WINBUF_ARGB(255, r, g, b)

#define WINBUF_RED       WINBUF_RGB(255, 0, 0)
#define WINBUF_GREEN     WINBUF_RGB(0, 255, 0)
#define WINBUF_BLUE      WINBUF_RGB(0, 0, 255)
#define WINBUF_WHITE     WINBUF_RGB(255, 255, 255)
#define WINBUF_BLACK     WINBUF_RGB(0, 0, 0)
#define WINBUF_GRAY      WINBUF_RGB(195, 195, 195)
#define WINBUF_LEAD      WINBUF_RGB(127, 127, 127)
#define WINBUF_YELLOW    WINBUF_RGB(255, 255, 0)
#define WINBUF_NONE      WINBUF_ARGB(0, 0, 0, 0)

#ifdef CONFIG_WINBUF_FIFO_MSG_NR
#define WINBUF_FIFO_MSG_NR CONFIG_WINBUF_FIFO_MSG_NR   /* def msg number */
#else
#define WINBUF_FIFO_MSG_NR 128
#endif

#ifdef CONFIG_WINBUF_POLL_YIELD_TIMES
#define WINBUF_POLL_YIELD_TIMES CONFIG_WINBUF_POLL_YIELD_TIMES 
#else
#define WINBUF_POLL_YIELD_TIMES 100 /* poll 100 times no event will yield out */
#endif

typedef struct Winbuf
{
    NX_List list;
    NX_U32 * buf; /* pixel buf */
    NX_Size width;
    NX_Size height;
    NX_Offset x;
    NX_Offset y;
    NX_Fifo * fifo;
#ifdef CONFIG_WINBUF_SHM
    NX_Solt shm;
    NX_Solt shmAddr;
    char shmName[NX_SHAREMEM_NAME_LEN];
#endif
} Winbuf;

typedef struct WinbufRegion
{
    NX_Size width;
    NX_Size height;
    NX_Offset x;
    NX_Offset y;
} WinbufRegion;

Winbuf * CreateWinbuf(NX_Size width, NX_Size height);
NX_Error DestroyWinbuf(Winbuf * wb);
NX_Error TopWinbuf(Winbuf * wb);
NX_Error FlushWinbuf(Winbuf * wb, WinbufRegion * region);
Winbuf * GetTopWinbuf(void);
void SetRootWinbuf(Winbuf * wb);
NX_Error SetWinbufPostion(Winbuf * wb, NX_Offset x, NX_Offset y);
Winbuf * GetRootWinbuf(void);
NX_Size GetBaseWinbufWidth(void);
NX_Size GetBaseWinbufHeight(void);

NX_Error DrawRectWinbuf(Winbuf * wb, WinbufRegion * region, NX_U32 color);
NX_Error DrawWinbufBlock(Winbuf * wb, NX_U32 *buf);

NX_Error WinbufInit(void);
NX_Error WinbufLoop(void);

NX_Error PutWinbufMsg(Winbuf * wb, WinbufMsg * msg);
NX_Error GetWinbufMsg(Winbuf * wb, WinbufMsg * msg);

NX_Error WinbufRunUdriver(void);

#endif /* __WINBUF_H__ */
